﻿//#define DB_FREE

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using BankApp.Models;
using IBS.Bll;
using IBS.ServiceContracts;
using ED = IBS.Model.ExternalDataService;

namespace BankApp.Controllers
{
    public class ExchangeRatesController : Controller
    {
        private ICurrencyService currencyService;

        public ExchangeRatesController()
        {
            var container = new IbsContainer();
            this.currencyService = container.CurrencyService;
        }

        //
        // GET: /ExchangeRates/

        public ActionResult Index(DateTime? fromDate = null, DateTime? toDate = null, string currency = null)
        {
            var from = fromDate ?? DateTime.Today;
            var to = toDate ?? DateTime.Today;
            ViewBag.FromDate = from.ToString("MM/dd/yyyy");
            ViewBag.ToDate = to.ToString("MM/dd/yyyy");
#if DB_FREE 
            var rates = new List<ExchangeRate> { 
                new ExchangeRate 
                {
                    Currency = "USD",
                    Ask = 8200,
                    Bid = 8320,
                    Date = DateTime.Today.AddDays(-1),
                },
                new ExchangeRate 
                {
                    Currency = "USD",
                    Ask = 8100,
                    Bid = 8400,
                    Date = DateTime.Today,
                },
                new ExchangeRate 
                {
                    Currency = "EUR",
                    Ask = 10000,
                    Bid = 11000,
                    Date = DateTime.Today,
                },
            };
            ViewBag.FromDate = from;
            ViewBag.ToDate = to;
            ViewBag.Currency = currency;
            return View(rates.Where(_ => from <= _.Date && _.Date <= to 
                && (currency == null || currency.ToUpper() == "ALL" || _.Currency == currency)).ToList());
#else
            var currencies = currencyService.GetAllCurrencies();
            var rates = new List<ExchangeRate>();
            foreach (var _currency in currencies)
            {
                if (!String.IsNullOrWhiteSpace(currency) && currency.ToUpper() != "ALL" && _currency.ISO.ToUpper() != currency.ToUpper())
                    continue;

                rates.AddRange(_currency.CurrencyExchangeRate.Where(_ => from <= _.Date.Date && _.Date.Date <= to).Select(_ =>
                    new ExchangeRate
                        {
                            Currency = _currency.ISO,
                            Ask = _.AskRate,
                            Bid = _.BidRate,
                            Date = _.Date
                        }));
            }

            return View(rates);
#endif
        }

        private decimal? Fetch(string c, ED.Provider provider, bool safe = false)
        {
            decimal? rate = null;
            try
            {
                var fetchRes = ED.fetchRates(new[] { "BYR" }, c, DateTime.Today, provider).FirstOrDefault();
                if (fetchRes != null) rate = fetchRes.Rate;
            }
            catch
            {
                if (!safe) throw;
            }
            return rate;
        }

        public ActionResult Current()
        {
            try
            {
                var currencies =
#if !DB_FREE
    currencyService.GetAllCurrencies().Where(_ => _.ISO != "BYR").Select(_ => _.ISO).Distinct().ToArray();
#else
    new[] { "USD", "EUR", "CAD", "AUD", "JPY" };
#endif
                var rates = new List<CurrentRate>();
                foreach (var c in currencies)
                {
                    rates.Add(new CurrentRate 
                    {
                        Currency = c,
                        NBRB = Fetch(c, ED.Provider.NBRB).Value,
                        Yahoo = Fetch(c, ED.Provider.Yahoo).Value,
                        ECB = null, //FetchFrom(c, ED.Provider.ECB, true), //for BYR will be null
                        FED = null, //FetchFrom(c, ED.Provider.FED, true), //for BYR will be null
                        Google = Fetch(c, ED.Provider.Google, true),
                    });
                }

                return View(rates);
            }
            catch
            {
                ModelState.AddModelError("", "NBRB currency service is currently unavailable");
                return View(Enumerable.Empty<CurrentRate>());
            }
        }

        [Authorize(Roles = "admin")]
        public ActionResult Create()
        {
            ViewBag.CreateNew = true;
            return View("Details", new ExchangeRate { Date = DateTime.Today });
        }

        [Authorize(Roles = "admin")]
        public ActionResult Edit(string c, decimal ask, decimal bid)
        {
            ViewBag.CreateNew = false;
            return View("Details", new ExchangeRate { Currency = c, Date = DateTime.Today, Ask = ask, Bid = bid });
        }

        [HttpPost]
        [Authorize(Roles = "admin")]
        public ActionResult Update(ExchangeRate rate, bool createNew = false)
        {
            if (ModelState.IsValid)
            {
#if !DB_FREE
                var currency = currencyService.GetCurrency(rate.Currency);
                currencyService.SetCurrencyExchangeRate(rate.Currency,
                    new IBS.Model.CurrencyExchangeRate
                    {
                        CurrencyId = currency.Id,
                        Currency = currency,
                        AskRate = rate.Ask,
                        BidRate = rate.Bid,
                        Date = DateTime.Today
                    });
#endif
                return RedirectToAction("Index");
            }
            ViewBag.CreateNew = createNew;
            return View("Details", rate);
        }
    }
}